home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / silhouette.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  4.7 KB  |  249 lines

  1.  
  2. /* silhouette.c - by Tom McReynolds, SGI */
  3.  
  4. /* Doing Silhouette Edges with stencil */
  5.  
  6. #include <GL/glut.h>
  7. #include <stdlib.h>
  8. #include <math.h>
  9.  
  10. enum {
  11.   CONE = 1
  12. };
  13.  
  14. /* Draw a cone */
  15. void
  16. cone(void)
  17. {
  18.   glPushMatrix();
  19.   glTranslatef(0.f, 0.f, -30.f);
  20.   glCallList(CONE);
  21.   glPopMatrix();
  22. }
  23.  
  24. /* Draw a torus */
  25. void
  26. torus(void)
  27. {
  28.   glutSolidTorus(10., 20., 20, 20);
  29. }
  30.  
  31. enum {
  32.   SIL, OBJ, SIL_AND_OBJ, TOGGLE
  33. };
  34.  
  35. int rendermode = OBJ;
  36.  
  37. void (*curobj) (void) = cone;
  38.  
  39. void 
  40. menu(int mode)
  41. {
  42.   switch (mode) {
  43.   case SIL:
  44.   case OBJ:
  45.   case SIL_AND_OBJ:
  46.     rendermode = mode;
  47.     break;
  48.   case TOGGLE:
  49.     if (curobj == cone)
  50.       curobj = torus;
  51.     else
  52.       curobj = cone;
  53.     break;
  54.   }
  55.   glutPostRedisplay();
  56. }
  57.  
  58. int winWidth = 512;
  59. int winHeight = 512;
  60.  
  61. /* used to get current width and height of viewport */
  62. void
  63. reshape(int wid, int ht)
  64. {
  65.   glViewport(0, 0, wid, ht);
  66.   winWidth = wid;
  67.   winHeight = ht;
  68.   glutPostRedisplay();
  69. }
  70.  
  71. GLfloat viewangle;
  72.  
  73. void
  74. drawsilhouette(void)
  75. {
  76.   int i;
  77.  
  78.   glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  79.   glEnable(GL_STENCIL_TEST);
  80.   glStencilFunc(GL_ALWAYS, 1, 1);
  81.   glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
  82.   glDisable(GL_DEPTH_TEST);  /* so the depth buffer doesn't change */
  83.   for (i = -1; i < 2; i += 2) {  /* set stencil around object */
  84.     glViewport(i, 0, winWidth + i, winHeight);
  85.     curobj();
  86.   }
  87.   for (i = -1; i < 2; i += 2) {
  88.     glViewport(0, i, winWidth, winHeight + i);
  89.     curobj();
  90.   }
  91.  
  92.   /* cut out stencil where object is */
  93.   glViewport(0, 0, winWidth, winHeight);
  94.   glStencilFunc(GL_ALWAYS, 0, 0);
  95.   curobj();
  96.  
  97.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  98.  
  99.   glStencilFunc(GL_EQUAL, 1, 1);
  100.  
  101.   glDisable(GL_LIGHTING);
  102.   glColor3f(1.f, 0.f, 0.f);  /* draw silhouette red */
  103.   glRotatef(-viewangle, 0.f, 1.f, 0.f);
  104.   glRecti(-50, -50, 50, 50);
  105.   glRotatef(viewangle, 0.f, 1.f, 0.f);
  106.   glEnable(GL_DEPTH_TEST);
  107.   glEnable(GL_LIGHTING);
  108.   glDisable(GL_STENCIL_TEST);
  109. }
  110.  
  111. void
  112. redraw(void)
  113. {
  114.   /* clear stencil each time */
  115.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  116.  
  117.   glPushMatrix();
  118.   glRotatef(viewangle, 0.f, 1.f, 0.f);
  119.  
  120.   switch (rendermode) {
  121.   case SIL:
  122.     drawsilhouette();
  123.     break;
  124.   case SIL_AND_OBJ:
  125.     drawsilhouette();
  126.     curobj();
  127.     break;
  128.   case OBJ:
  129.     curobj();
  130.     break;
  131.   }
  132.  
  133.   glPopMatrix();
  134.   glutSwapBuffers();
  135. }
  136.  
  137. /* animate scene by rotating */
  138. enum {
  139.   ANIM_LEFT, ANIM_RIGHT
  140. };
  141. int animDirection = ANIM_LEFT;
  142.  
  143. void 
  144. anim(void)
  145. {
  146.   if (animDirection == ANIM_LEFT)
  147.     viewangle -= 1.f;
  148.   else
  149.     viewangle += 1.f;
  150.   glutPostRedisplay();
  151. }
  152.  
  153. /* ARGSUSED1 */
  154. /* special keys, like array and F keys */
  155. void 
  156. special(int key, int x, int y)
  157. {
  158.   switch (key) {
  159.   case GLUT_KEY_LEFT:
  160.     glutIdleFunc(anim);
  161.     animDirection = ANIM_LEFT;
  162.     break;
  163.   case GLUT_KEY_RIGHT:
  164.     glutIdleFunc(anim);
  165.     animDirection = ANIM_RIGHT;
  166.     break;
  167.   case GLUT_KEY_UP:
  168.   case GLUT_KEY_DOWN:
  169.     glutIdleFunc(0);
  170.     break;
  171.   }
  172. }
  173.  
  174. /* ARGSUSED1 */
  175. void 
  176. key(unsigned char key, int x, int y)
  177. {
  178.   switch (key) {
  179.   case 'a':
  180.     viewangle -= 10.f;
  181.     glutPostRedisplay();
  182.     break;
  183.   case 's':
  184.     viewangle += 10.f;
  185.     glutPostRedisplay();
  186.     break;
  187.   case '\033':
  188.     exit(0);
  189.   }
  190. }
  191.  
  192. int picked_object;
  193. int xpos = 0, ypos = 0;
  194. int newxpos, newypos;
  195. int startx, starty;
  196.  
  197. int
  198. main(int argc, char **argv)
  199. {
  200.   static GLfloat lightpos[] =
  201.   {25.f, 50.f, -50.f, 1.f};
  202.   static GLfloat cone_mat[] =
  203.   {0.f, .5f, 1.f, 1.f};
  204.   GLUquadricObj *cone, *base;
  205.  
  206.   glutInit(&argc, argv);
  207.   glutInitWindowSize(512, 512);
  208.   glutInitDisplayMode(GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE);
  209.   (void) glutCreateWindow("silhouette edges");
  210.   glutDisplayFunc(redraw);
  211.   glutKeyboardFunc(key);
  212.   glutSpecialFunc(special);
  213.   glutReshapeFunc(reshape);
  214.  
  215.   glutCreateMenu(menu);
  216.   glutAddMenuEntry("Object", OBJ);
  217.   glutAddMenuEntry("Silhouette Only", SIL);
  218.   glutAddMenuEntry("Object and Silhouette", SIL_AND_OBJ);
  219.   glutAddMenuEntry("Toggle Object", TOGGLE);
  220.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  221.  
  222.   glEnable(GL_DEPTH_TEST);
  223.   glEnable(GL_CULL_FACE);
  224.   glEnable(GL_LIGHTING);
  225.   glEnable(GL_LIGHT0);
  226.  
  227.   glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  228.   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  229.  
  230.   /* make display list for cone; for efficiency */
  231.  
  232.   glNewList(CONE, GL_COMPILE);
  233.   cone = gluNewQuadric();
  234.   base = gluNewQuadric();
  235.   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, cone_mat);
  236.   gluQuadricOrientation(base, GLU_INSIDE);
  237.   gluDisk(base, 0., 15., 32, 1);
  238.   gluCylinder(cone, 15., 0., 60., 32, 32);
  239.   gluDeleteQuadric(cone);
  240.   gluDeleteQuadric(base);
  241.   glEndList();
  242.  
  243.   glMatrixMode(GL_PROJECTION);
  244.   glOrtho(-50., 50., -50., 50., -50., 50.);
  245.   glMatrixMode(GL_MODELVIEW);
  246.   glutMainLoop();
  247.   return 0;             /* ANSI C requires main to return int. */
  248. }
  249.